/**
 * 
 */
package in.electromedicalabs.moviesorter;

import java.io.File;
import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;

/**
 * Takes care of finding and renaming movie folders and files
 * 
 * @author @nkit Prasad & Bhavin Mehta
 * @version $Revision: 1.0 $
 */
public class MovieUtils {

	/**
	 * The number of info file fields in the filename
	 */
	private static final int FILENAME_FILD_COUNT = 3;
	/**
	 * Files with these extensions will be processed if not found with a folder
	 * in the base directory
	 */
	private static String[] movieExtensions = { ".avi", ".divx", ".flv",
			".m4v", ".mkv", ".mov", ".mp4", ".mpeg", ".mpg", ".rm", ".vob",
			".xvid" };

	private static String[] junkStrings = { "[", "(", "dvdrip", "xvid", "axxo",
			"scam", "AXXO" };

	/**
	 * Method main.
	 * 
	 * @param args
	 *            String[]
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static void main(String[] args) throws ClientProtocolException,
			IOException {

		StatusScreen.startStatusDisplay();
		StatusScreen.printStatus("Organizing your movie collection...");

		// //////////////////////////////////////////////////////////////////////////////////////////

		int status = HttpUtils.testServer();
		if (status != 0) {
			StatusScreen
					.printStatus("\t There is a Problem Detected .... Aborting..");
		} else {
			// Internet Connectivity Seems Ok..
			StatusScreen.printStatus("\nConnectivity Seems Ok .. Begning Work");
			// Check for Write Permissions..
			HttpUtils.advertise();
			HttpUtils.initialize();

			processBaseDirFolders();
			processBaseDirFiles();

			HttpUtils.shutdown();
			StatusScreen.printStatus("\nCompleted Successfully !!!");
			StatusScreen
					.printStatus("\t\t Send Feedbacks to : ankit4u3@gmail.com ");
		}
	}

	/**
	 * Processes folders of the base directory
	 * 
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private static void processBaseDirFolders() throws ClientProtocolException,
			IOException {
		File baseDir = new File(".");
		if (baseDir.canWrite() || baseDir.canRead()) {
			processDir(baseDir);
		} else {
			StatusScreen
					.printStatus("Error Reading the Folder .. Persmission Error ..");
		}

	}

	/**
	 * Processes the movies with out folders in the base directory
	 * 
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private static void processBaseDirFiles() throws ClientProtocolException,
			IOException {
		File baseDir = new File(".");
		for (File file : baseDir.listFiles()) {
			if (!file.isDirectory()) {
				processFile(file);
			}
		}
	}

	/**
	 * Adds folder to movies with out folders
	 * 
	 * @param file
	 *            File
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private static void processFile(File file) throws ClientProtocolException,
			IOException {
		String fileName = file.getName().toLowerCase();
		boolean correctExtension = false;
		for (String extension : movieExtensions) {
			if (fileName.endsWith(extension)) {
				correctExtension = true;
				break;
			}
		}

		if (correctExtension) {
			String[] fileParts = fileName.split("\\.");
			String delimiter = fileParts[fileParts.length - 1];
			File newFile = new File(fileName.split(delimiter)[0]);
			if (newFile.mkdir()) {
				file.renameTo(new File(newFile.getAbsoluteFile().toString()
						+ File.separator + fileName));
				processDir(newFile);
			}
		}
	}

	/**
	 * Renames movie directory and adds info file
	 * 
	 * @param directory
	 *            File
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	private static void processDir(File directory)
			throws ClientProtocolException, IOException {
		for (File file : directory.listFiles()) {
			if (file.isDirectory()) {
				processDir(file.getAbsoluteFile());
			}
		}

		if (directory.canWrite()) {
			Movie movie = null;
			File newFileName = null;
			String rawMovieTitle = directory.getName();
			String refinedMovieTitle = getRefinedMovieTitle(rawMovieTitle
					.toLowerCase());
			try {
				if (refinedMovieTitle == null) {
					return;
				}
				movie = new Movie(refinedMovieTitle);
				movie.writeToFile(directory);
				newFileName = movie.getNewFileName();
				if (newFileName != null) {
					directory.renameTo(newFileName);
					StatusScreen.printStatus("Lookup & rename complete for "
							+ rawMovieTitle);
				}
			} catch (JSONException e) {
				StatusScreen.printStatus("No film found for: " + rawMovieTitle);
			}
		} else {
			StatusScreen.printStatus(directory.getAbsolutePath()
					+ " is Read Only... not touching it.");
		}
	}

	/**
	 * Removes junk characters for the movie title
	 * 
	 * @param title
	 * @return
	 */
	private static String getRefinedMovieTitle(String title) {
		if (title.charAt(0) == '.'
				|| title.split(Movie.SEPERATOR).length == FILENAME_FILD_COUNT) {
			return null;
		}

		title = title.replace('.', ' ');
		title = title.replace('-', ' ');
		title = title.replace('_', ' ');

		for (String junkStr : junkStrings) {
			int junkStringPosition = title.indexOf(junkStr);
			if (junkStringPosition > 0) {
				title = title.substring(0, junkStringPosition - 1);
			}
		}

		String[] titleWords = title.split(" ");
		for (String word : titleWords) {
			try {
				int year = Integer.parseInt(word);
				if (year >= 1900 && year <= 2050) {
					int yearPosition = title.indexOf(year + "");
					if (yearPosition > 0) {
						title = title.substring(0, yearPosition);
						return title;
					}
				}
			} catch (NumberFormatException e) {
				// Do nothing
			}
		}

		return title;
	}

	public static void diagnosticrun() {

		// Check the following parameters for Smooth Working of the program...
		// 1. Internet Connection
		// 2. Folder is accessible or not .. throw error accordingly..
		// 3. Email to Developers... Using Email System..Regarding the counter
		// downloaded and Runned..

	}

}
